﻿namespace MainGame.GameScreens
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;

    using MainGame.Components;

    using XGameLibrary.Input;
    using XGameLibrary.ScreenManager;
    using XGameLibrary.SpriteClasses;
    using XGameLibrary.TileEngine;
    using XGameLibrary.Controls;

    public class HomeScreen : BaseGameState
    {
        Engine engine;

        TileMap map;
        Player player;
        AnimatedSprite sprite;

        private SoundEffectInstance walking;

        public HomeScreen(Game game, GameStateManager manager, Player player, AnimatedSprite sprite) :
            base(game, manager)
        {
            this.engine = new Engine(32, 32);
            this.player = player;
            this.sprite = sprite;
        }

        protected override void LoadContent()
        {
            base.LoadContent();

            Texture2D tilesetTexture = this.GameRef.Content.Load<Texture2D>(@"Images\Tilesets\room_spritesheet");
            Tileset tileset = new Tileset(tilesetTexture, 8, 8, 32, 32);

            List<Tileset> tilesets = new List<Tileset>();
            tilesets.Add(tileset);

            MapLayer layer = new MapLayer(7, 10);

            using (StreamReader layerFile = new StreamReader(@"TempMaps\home.txt"))
            {
                for (int y = 0; y < layer.Height; y++)
                {
                    string line = layerFile.ReadLine();
                    string[] tiles = line.Replace(']', ' ').Split('[');

                    for (int x = 0; x < layer.Width; x++)
                    {
                        int tileNum = int.Parse((tiles[x + 1][0]).ToString()) * 8 + int.Parse((tiles[x + 1][2]).ToString());

                        Tile tile = new Tile(tileNum, 0);

                        layer.SetTile(x, y, tile);
                    }
                }
            }

            MapLayer splatter = new MapLayer(7, 10);
            using (StreamReader splatterFile = new StreamReader(@"TempMaps\homeSplatterOne.txt"))
            {
                for (int y = 0; y < layer.Height; y++)
                {
                    string line = splatterFile.ReadLine();
                    string[] tiles = line.Replace(']', ' ').Split('[');

                    for (int x = 0; x < layer.Width; x++)
                    {
                        if (tiles[x + 1][0] == 'x')
                        {
                            Tile tileTemp = new Tile(20, 0);
                            splatter.SetTile(x, y, tileTemp);
                            continue;
                        }
                        int tileNum = int.Parse((tiles[x + 1][0]).ToString()) * 8 + int.Parse((tiles[x + 1][2]).ToString());

                        Tile tile = new Tile(tileNum, 0);

                        splatter.SetTile(x, y, tile);
                    }
                }
            }

            MapLayer splatterTwo = new MapLayer(7, 10);
            using (StreamReader splatterFile = new StreamReader(@"TempMaps\homeSplatterTwo.txt"))
            {
                for (int y = 0; y < layer.Height; y++)
                {
                    string line = splatterFile.ReadLine();
                    string[] tiles = line.Replace(']', ' ').Split('[');

                    for (int x = 0; x < layer.Width; x++)
                    {
                        if (tiles[x + 1][0] == 'x')
                        {
                            Tile tileTemp = new Tile(20, 0);
                            splatterTwo.SetTile(x, y, tileTemp);
                            continue;
                        }
                        int tileNum = int.Parse((tiles[x + 1][0]).ToString()) * 8 + int.Parse((tiles[x + 1][2]).ToString());

                        Tile tile = new Tile(tileNum, 0);

                        splatterTwo.SetTile(x, y, tile);
                    }
                }
            }

            List<MapLayer> mapLayers = new List<MapLayer>();
            mapLayers.Add(layer);
            mapLayers.Add(splatter);
            mapLayers.Add(splatterTwo);

            this.map = new TileMap(tilesets, mapLayers);

            this.walking = AnimatedSprite.WalkingOnWood.CreateInstance();

            this.sprite.Position = new Vector2(0 * 32, 4 * 32);
            this.player.Camera.LockToSprite(this.sprite);
        }

        public override void Update(GameTime gameTime)
        {
            this.player.Update(gameTime);
            this.sprite.Update(gameTime);

            Vector2 motion = new Vector2();

            if (InputHandler.KeyDown(Keys.W))
            {
                this.sprite.CurrentAnimation = AnimationKey.Up;
                motion.Y = -1;
            }
            else if (InputHandler.KeyDown(Keys.S))
            {
                this.sprite.CurrentAnimation = AnimationKey.Down;
                motion.Y = 1;
            }

            if (InputHandler.KeyDown(Keys.A))
            {
                this.sprite.CurrentAnimation = AnimationKey.Left;
                motion.X = -1;
            }
            else if (InputHandler.KeyDown(Keys.D))
            {
                this.sprite.CurrentAnimation = AnimationKey.Right;
                motion.X = 1;
            }

            if (motion != Vector2.Zero)
            {
                sprite.IsAnimating = true;
                motion.Normalize();

                if ((this.sprite.Position.Y > 3 * 32 && this.sprite.Position.Y < 5 * 32) && this.sprite.Position.X < 4)
                {
                    if (motion.X < 0)
                    {
                        TileMap.MapHeight = 32;
                        TileMap.MapWidth = 32;

                        this.GameRef.GamePlayScreen.sprite.Position = new Vector2(31 * 32 - 4, 28 * 32);

                        this.StateManager.PopState();
                    }
                }

                this.sprite.Position += motion * this.sprite.Speed;
                this.sprite.LockToMap();

                if (this.player.Camera.CameraMode == CameraMode.Follow)
                {
                    player.Camera.LockToSprite(this.sprite);
                }

                this.walking.Play();
            }
            else
            {
                this.sprite.IsAnimating = false;
                this.sprite.animations[this.sprite.CurrentAnimation].Reset();
            }

            float deltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (this.player.stamina < 100)
            {
                this.player.stamina = Math.Max(0f, this.player.stamina + deltaTime);

                if (this.sprite.Position.X > 4 * 32)
                {
                    if (this.sprite.Position.Y > 7 * 32)
                    {
                        for (int i = 0; i < 50; i++)
                            this.player.stamina = Math.Max(0f, this.player.stamina + deltaTime);
                    }
                }
            }

            if (InputHandler.KeyReleased(Keys.F))
            {
                this.player.Camera.ToggleCameraMode();
                if (this.player.Camera.CameraMode == CameraMode.Follow)
                {
                    player.Camera.LockToSprite(this.sprite);
                }
            }

            if (this.player.Camera.CameraMode != CameraMode.Follow)
            {
                if (InputHandler.KeyReleased(Keys.C))
                {
                    this.player.Camera.LockToSprite(this.sprite);
                }
            }

            if (InputHandler.KeyReleased(Keys.Escape))
            {
                this.GameRef.Exit();
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            this.GameRef.SpriteBatch.Begin(
                SpriteSortMode.Immediate,
                BlendState.AlphaBlend,
                SamplerState.PointClamp,
                null,
                null,
                null,
                Matrix.Identity);

            this.map.Draw(this.GameRef.SpriteBatch, this.player.Camera);
            this.sprite.Draw(gameTime, this.GameRef.SpriteBatch, this.player.Camera, this.player.stamina);

            base.Draw(gameTime);
            this.GameRef.SpriteBatch.End();
        }
    }
}
